#include "gofgame/common/ui/MessageDialog.h"
#include "gofgame/common/ui/DockLayout.h"
#include "gofgame/common/ui/TableLayout.h"
#include "gofgame/common/ui/DockLayoutData.h"

using namespace gofgame::common::ui;

MessageDialog::MessageDialog(MessageDialogType messageDialogType) {
	this->buttonContainer.initialize();
	this->okButton.initialize();
	this->cancelButton.initialize();
	this->buttonContainer->setHeight(60);
	this->okButton->setText("OK");
	this->cancelButton->setText("Cancel");
	this->messageDialogType = messageDialogType;

	//Fuck C++, here I want to call this->createMainComponent()
	//to initialize this->mainComponent to grantee
	//the mainComponent is not null before the invocation of init(),
	//
	//But in C++, the virtual method will not be consider as
	//virtual method if it is called in the constructor(This method)
	//
	//In Java/.NET, This is no problem 
	//
	//T_T
}

bool MessageDialog::init() {
	if (!Dialog::init()) {
		delete this;
		return false;
	}
	this->getContentContainer()->setLayout(new DockLayout());
	this->mainComponent = this->createMainComponent();
	this->getContentContainer()->addChild(mainComponent);
	this->buttonContainer->setLayoutData(new DockLayoutData(DockStyle_Bottom));
	this->getContentContainer()->addChild(this->buttonContainer);

	this->buttonContainer->setLayout(new TableLayout(this->buttonContainer->getHeight()));
	static_cast<TableLayout*>(this->buttonContainer->getLayout())->setCellPadding(10);
	static_cast<TableLayout*>(this->buttonContainer->getLayout())->addColumn(TableColumn::relative(1));	
	static_cast<TableLayout*>(this->buttonContainer->getLayout())->addColumn(TableColumn::relative(3));
	static_cast<TableLayout*>(this->buttonContainer->getLayout())->addColumn(TableColumn::relative(1));
	if (this->getMessageDialogType() == MessageDialogType_OKCancel) {
		static_cast<TableLayout*>(this->buttonContainer->getLayout())->addColumn(TableColumn::relative(3));
		static_cast<TableLayout*>(this->buttonContainer->getLayout())->addColumn(TableColumn::relative(1));
	}

	Ref<Component> space1, space2, space3;
	this->okButton->init();
	space1.initialize();
	space1->init();
	this->buttonContainer->addChild(space1);
	this->buttonContainer->addChild(this->okButton);
	space2.initialize();
	space2->init();
	this->buttonContainer->addChild(space2);
	if (this->getMessageDialogType() == MessageDialogType_OKCancel) {
		this->cancelButton->init();
		this->buttonContainer->addChild(this->cancelButton);
		space3.initialize();
		space3->init();
		this->buttonContainer->addChild(space3);
	}

	this->okButton->click() += event_handler<ComponentEventArgs>(this, &MessageDialog::okButton_click);
	this->cancelButton->click() += event_handler<ComponentEventArgs>(this, &MessageDialog::cancelButton_click);

	return true;
}

MessageDialogType MessageDialog::getMessageDialogType() const {
	return this->messageDialogType;
}

float MessageDialog::getButtonHeight() const {
	return this->buttonContainer->getHeight();
}

void MessageDialog::setButtonHeight(float buttonHeight) {
	this->buttonContainer->setHeight(buttonHeight);
	TableLayout *tableLayout = static_cast<TableLayout*>(this->buttonContainer->getLayout());
	if (tableLayout) {
		tableLayout->setMinRowHeight(buttonHeight);
	}
}

const char *MessageDialog::getMessage() const {
	Label *label = dynamic_cast<Label*>(this->mainComponent.unwrap());
	if (label) {
		return label->getText();
	} else {
		return nullptr;
	}
}

void MessageDialog::setMessage(const char *message) {
	Label *label = dynamic_cast<Label*>(this->mainComponent.unwrap());
	if (label) {
		label->setText(message);
	}
}

const char *MessageDialog::getOKText() const {
	return this->okButton->getText();
}

void MessageDialog::setOKText(const char *okText) {
	this->okButton->setText(okText);
}

const char *MessageDialog::getCancelText() const {
	return this->cancelButton->getText();
}

void MessageDialog::setCancelText(const char *cancelText) {
	this->cancelButton->setText(cancelText);
}

Brush *MessageDialog::getMessageBrush() const {
	Label *label = dynamic_cast<Label*>(this->mainComponent.unwrap());
	if (label) {
		return label->getBrush();
	} else {
		return Brush::white();
	}
}

void MessageDialog::setMessageBrush(Brush *messageBrush) {
	Label *label = dynamic_cast<Label*>(this->mainComponent.unwrap());
	if (label) {
		label->setBrush(messageBrush);
	}
}

Brush *MessageDialog::getButtonBrush(MessageButtonType messageButton) const {
	if (messageButton == MessageButtonType_Any || messageButton == MessageButtonType_OK) {
		return this->okButton->getBrush();
	}
	if (messageButton == MessageButtonType_Any || messageButton == MessageButtonType_Cancel) {
		return this->cancelButton->getBrush();
	}
	return nullptr;
}

void MessageDialog::setButtonBrush(Brush *buttonBrush, MessageButtonType messageButton) {
	if (messageButton == MessageButtonType_Any || messageButton == MessageButtonType_OK) {
		this->okButton->setBrush(buttonBrush);
	}
	if (messageButton == MessageButtonType_Any || messageButton == MessageButtonType_Cancel) {
		this->cancelButton->setBrush(buttonBrush);
	}
}

Brush *MessageDialog::getButtonBackgroundBrush(MessageButtonType messageButton) const {
	if (messageButton == MessageButtonType_Any || messageButton == MessageButtonType_OK) {
		return this->okButton->getBackgroundBrush();
	}
	return this->cancelButton->getBackgroundBrush();
}

void MessageDialog::setButtonBackgroundBrush(Brush *buttonBackgroundBrush, MessageButtonType messageButton) {
	if (messageButton == MessageButtonType_Any || messageButton == MessageButtonType_OK) {
		this->okButton->setBackgroundBrush(buttonBackgroundBrush);
	}
	if (messageButton == MessageButtonType_Any || messageButton == MessageButtonType_Cancel) {
		this->cancelButton->setBackgroundBrush(buttonBackgroundBrush);
	}
}

Brush *MessageDialog::getButtonPressedBackgroundBrush(MessageButtonType messageButton) const {
	if (messageButton == MessageButtonType_Any || messageButton == MessageButtonType_OK) {
		return this->okButton->getPressedBackgroundBrush();
	}
	return this->cancelButton->getPressedBackgroundBrush();
}

void MessageDialog::setButtonPressedBackgroundBrush(Brush *buttonPressedBackgroundBrush, MessageButtonType messageButton) {
	if (messageButton == MessageButtonType_Any || messageButton == MessageButtonType_OK) {
		this->okButton->setPressedBackgroundBrush(buttonPressedBackgroundBrush);
	}
	if (messageButton == MessageButtonType_Any || messageButton == MessageButtonType_Cancel) {
		this->cancelButton->setPressedBackgroundBrush(buttonPressedBackgroundBrush);
	}
}

Ref<Component> MessageDialog::createMainComponent() {
	Ref<Label> label;
	label.initialize();
	label->init();
	return label;
}

void MessageDialog::okButton_click(void *sender, ComponentEventArgs &e) {
	this->close(DialogResult_OK);
}

void MessageDialog::cancelButton_click(void *sender, ComponentEventArgs &e) {
	this->close(DialogResult_Cancel);
}
